home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
intrvews
/
xgrab.lha
/
xgrab
/
grabst
/
copy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-06
|
6KB
|
276 lines
/**
GRAB Graph Layout and Browser System
Copyright (c) 1986, 1988 Regents of the University of California
Copyright (c) 1989, Tera Computer Company
**/
/**
copy.c -- routines to copy parts of the digraph data structure
**/
#include "malloc.h"
#include "attribute.h"
#include "digraph.h"
char **copy_attr();
INEDGE *copy_in_edges();
OUTEDGE *copy_out_edges();
VERTEX *insert_vertex();
LEVEL *copy_levels();
NODE *copy_node(digraph, node)
DIGRAPH *digraph;
NODE *node;
/**
copy_node makes a copy of the node and returns it.
digraph should be the *new node's* digraph.
**/
{
NODE *n;
if (node == NULL)
{
return NULL;
}
else
{
new(n, NODE);
n->coalescer_vno = node->coalescer_vno;
n->coalesced = node->coalesced;
n->coalescer = node->coalescer;
n->out_edges = copy_out_edges(digraph, node);
n->in_edges = copy_in_edges(node);
n->attributes = copy_attr(node->attributes, NNodeAttr(digraph));
init_set(Expansion(n));
copy_set(Expansion(n), Expansion(node));
init_set(Succ_set(n));
copy_set(Succ_set(n), Succ_set(node));
init_set(Ante_set(n));
copy_set(Ante_set(n), Ante_set(node));
copy_member(Node_member(n), Node_member(node));
X_position(n) = X_position(node);
Y_position(n) = Y_position(node);
Shape(n) = Shape(node);
Brush(n) = Brush(node);
Color(n) = Color(node);
Displayed(n) = Displayed(node);
Half_width(n) = Half_width(node);
Half_height(n) = Half_height(node);
n->vertex = insert_vertex(digraph, Name(node));
Vno(n) = Vno(node);
return n;
}
} /* copy_node */
char **copy_attr(attr, num)
char **attr;
int num;
/**
copy_attr copies *any* array of character pointers of length num and
returns the copy. Its used primarily to copy node or edge attributes
**/
{
int i;
char **a;
a = (char **) malloc(sizeof(char *) * num);
for (i = 0; i < num; i++)
{
strsave(a[i], attr[i]);
}
return a;
}
copy_member(m, member)
MEMBER *m, *member;
/**
copy the "member" fields of a node
**/
{
Last_dummy(m) = Last_dummy(member);
Level_no(m) = Level_no(member);
Position(m) = Position(member);
Status(m) = Status(member);
Is_layed(m) = Is_layed(member);
Bc(m, UP) = Bc(member, UP);
Bc(m, DOWN) = Bc(member, DOWN);
Priority(m, UP) = Priority(member, UP);
Priority(m, DOWN) = Priority(member, DOWN);
/* the following fields are set when levels are assigned */
Prev_member(m) = Next_member(m) = NULL;
}
OUTEDGE *copy_out_edges(digraph, node)
DIGRAPH *digraph;
NODE *node;
/**
make a copy of the out edges of a node. For this to work, the vno's
of digraph must correspond exactly to the vno's of the old digraph
**/
{
OUTEDGE *edge, *e, *t;
e = NULL;
all_out_edges(node, edge)
loop
new(t, OUTEDGE);
t->next = e;
e = t;
Brush(t) = Brush(edge);
Color(t) = Color(edge);
Ord(t) = Ord(edge);
t->attributes = copy_attr(edge->attributes, NEdgeAttr(digraph));
t->edge_reversed = edge->edge_reversed;
t->to_vno = edge->to_vno;
endloop
return e;
} /* copy_out_edges */
INEDGE *copy_in_edges(node)
NODE *node;
/**
make a copy of the out edges of a node. For this to work, the vno's
of the new digraph must correspond exactly to the vno's of the old
digraph
**/
{
INEDGE *edge, *e, *t;
e = NULL;
all_in_edges(node, edge)
loop
new(t, INEDGE);
t->next = e;
e = t;
Ord(t) = Ord(edge);
t->edge_reversed = edge->edge_reversed;
t->from_vno = edge->from_vno;
endloop;
return e;
} /* copy_in_edges */
DIGRAPH *copy_digraph(digraph)
DIGRAPH *digraph;
/**
copy_digraph steps through a digraph and creates a new copy of it.
**/
{
int i;
DIGRAPH *d;
if (digraph == NULL)
{
return NULL;
}
new(d, DIGRAPH);
strsave(d->title, Title(digraph));
d->lastnode = digraph->lastnode;
d->num_node_attributes = digraph->num_node_attributes;
d->num_edge_attributes = digraph->num_edge_attributes;
d->dist_node_attribute = digraph->dist_node_attribute;
d->dist_edge_attribute = digraph->dist_edge_attribute;
/* what a cheap trick! */
d->node_att_names = copy_attr(digraph->node_att_names, NNodeAttr(digraph));
d->edge_att_names = copy_attr(digraph->edge_att_names, NEdgeAttr(digraph));
/**
zero the hash table. It will be properly filled by the
insert_vertex calls in copy_node
**/
for (i = 0; i < MAXHASH; i++)
{
d->hashtbl[i] = NULL;
}
for (i = 0; i < MAXNODES; i++)
{
d->nodes[i] = copy_node(d, digraph->nodes[i]);
}
d->levels = copy_levels(d, digraph);
return d;
} /* copy_digraph */
LEVEL *copy_levels(digraph, digraph2)
DIGRAPH *digraph, *digraph2;
/**
copy_levels copies the levels of digraph2 to digraph, and, as a side
effect, sets the Prev_member and Next_member values of the nodes to their
proper values
**/
{
LEVEL *level, *l, *t;
MEMBER *m, *tmp, *last;
VNO vno;
l = NULL;
digraph->lastlevel = l;
each_level(digraph2, level)
loop
new(t, LEVEL);
t->prev = digraph->lastlevel;
t->next = NULL;
if (l == NULL)
{
l = t;
}
else
{
digraph->lastlevel->next = t;
}
digraph->lastlevel = t;
Lno(t) = Lno(level);
Num_cross(t) = Num_cross(level);
Offset(t) = Offset(level);
init_set(Members(t));
copy_set(Members(t), Members(level));
m = NULL;
last = NULL;
/* Set the next and prev member fields to their proper values */
each_element(Members(level), vno)
loop
tmp = Member(digraph, vno);
tmp->prev = last;
tmp->next = NULL;
if (m == NULL)
{
m = tmp;
}
else
{
last->next = tmp;
}
last = tmp;
endloop;
Order(t) = m;
endloop;
return l;
}